package top.lishuoboy.dependency.base.json;

import cn.hutool.core.util.ArrayUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;

import java.util.List;
import java.util.Map;

/**
 * JSON 工具类
 *
 * @author lishuoboy
 * @date 2022-2-8
 */
public class FastjsonUtil {
    /** fastjson SerializerFeature详解  https://blog.csdn.net/lishuoboy/article/details/124394291 */
    /** util 默认的 SerializerFeatureArr，提供外部使用 */
    public static final SerializerFeature[] defaultSerializerFeatureArr = new SerializerFeature[]{
            SerializerFeature.DisableCircularReferenceDetect,       // 禁用自引用
            SerializerFeature.SortField,                            // 启用 Bean按照key名称自然排序。默认未排序
            SerializerFeature.MapSortField,                         // 启用 Map 按照key名称自然排序。不生效
            SerializerFeature.WriteMapNullValue,                    // 输出null 对象
            SerializerFeature.IgnoreErrorGetter,                    // 忽略get异常
    };

    /** util 默认的 FeatureArr，提供外部使用 */
    public static final Feature[] defaultFeatureArr = new Feature[]{
            Feature.DisableCircularReferenceDetect,       // 禁用自引用
    };

    /** 序列化 */
    public static String toStr(Object obj, SerializerFeature... featureArr) {
        return JSON.toJSONString(obj, ArrayUtil.distinct(ArrayUtil.addAll(defaultSerializerFeatureArr, featureArr)));
    }

    /** 序列化 */
    public static String toStr(Object obj) {
        return toStr(obj, defaultSerializerFeatureArr);
    }

    /** 序列化并美化 */
    public static String toPrettyStr(Object obj, SerializerFeature... featureArr) {
        return JSON.toJSONString(obj, ArrayUtil.append(featureArr, SerializerFeature.PrettyFormat));
    }

    /** 序列化并美化 */
    public static String toPrettyStr(Object obj) {
        return toPrettyStr(obj, defaultSerializerFeatureArr);
    }

    /** 反序列化为<T> */
    public static <T> T toBean(String jsonStr, TypeReference<T> typeReference, Feature... featureArr) {
        return JSON.parseObject(jsonStr, typeReference, featureArr);
    }

    /** 反序列化为<T> */
    public static <T> T toBean(String jsonStr, TypeReference<T> typeReference) {
        return toBean(jsonStr, typeReference, defaultFeatureArr);
    }

    /** 反序列化为<T> */
    public static <T> T toBean(String jsonStr, Class<T> beanClass, Feature... featureArr) {
        return JSON.parseObject(jsonStr, beanClass, featureArr);
    }

    /** 反序列化为<T> */
    public static <T> T toBean(String jsonStr, Class<T> beanClass) {
        return toBean(jsonStr, beanClass, defaultFeatureArr);
    }

    /** 反序列化为List<T> */
    public static <T> List<T> toList(String jsonStr, TypeReference<List<T>> typeReference, Feature... featureArr) {
        return JSON.parseObject(jsonStr, typeReference.getType(), featureArr);
    }


    /** 反序列化为List<T> */
    public static <T> List<T> toList(String jsonStr, TypeReference<List<T>> typeReference) {
        return toList(jsonStr, typeReference, defaultFeatureArr);
    }

    /** 反序列化为List<T> */
    public static <T> List<T> toList(String jsonStr, Class<T> beanClass, Feature... featureArr) {
        return JSON.parseArray(jsonStr, beanClass, featureArr);
    }

    /** 反序列化为List<T> */
    public static <T> List<T> toList(String jsonStr, Class<T> beanClass) {
        return toList(jsonStr, beanClass, defaultFeatureArr);
    }

    /** 反序列化为Map<K, V> */
    public static <K, V> Map<K, V> toMap(String jsonStr, TypeReference<Map<K, V>> typeReference, Feature... featureArr) {
        return JSON.parseObject(jsonStr, typeReference.getType(), featureArr);
    }

    /** 反序列化为Map<K, V> */
    public static <K, V> Map<K, V> toMap(String jsonStr, TypeReference<Map<K, V>> typeReference) {
        return toMap(jsonStr, typeReference, defaultFeatureArr);
    }

    /** 反序列化为Map<String, Object> */
    public static Map<String, Object> toMap(String jsonStr, Feature... featureArr) {
        return toMap(jsonStr, new TypeReference<Map<String, Object>>() {
        }, featureArr);
    }

    /** 反序列化为Map<String, Object> */
    public static Map<String, Object> toMap(String jsonStr) {
        return toMap(jsonStr, defaultFeatureArr);
    }
}